package cascade.controller.pages.commands
{
	import cascade.App;
	import cascade.model.Page;
	
	import flight.commands.AsyncCommand;
	import flight.net.RemoteService;
	
	import mx.collections.ArrayCollection;
	import mx.rpc.Fault;

	public class CommandMovePage extends AsyncCommand
	{
		
		protected var page:Page;
		protected var oldParent:Page;
		protected var newParent:Page;
		protected var prevPage:Page;
		
		public function CommandMovePage(page:Page, newParent:Page)
		{
			this.page = page;
			this.newParent = newParent;
			this.oldParent = page.parent;
		}
		
		public override function execute():*
		{
			Cascade.busy.addBusy(this);
			var prevPageId:Number;
			var children:ArrayCollection;
			
			if (newParent) {
				if (!newParent.children)
					newParent.children = new ArrayCollection();
				children = newParent.children;
			} else {
				children = Cascade.model.siteTree;
			}
			
			var newIndex:Number = children.getItemIndex(page);
			if (newIndex != 0) {
				prevPage = children.getItemAt(newIndex - 1) as Page;
				prevPageId = prevPage.id;
			}
			
			Cascade.service.SiteService.movePage(
					page.id,
					newParent ? newParent.id : null,
					prevPageId ? prevPageId : null,
					result,
					fault);
			
		}
		
		protected function result(pages:Array):void {
			page.parent = newParent;
			if (oldParent && oldParent.children.length == 0)
				oldParent.children = null;
			
			var index:Number = Cascade.model.pages.getItemIndex(page);
			
			// don't change object references, just update the "VO" data for affected pages
			for (var i:Number = 0; i < pages.length; i++) {
				var affectedPage:Page = Cascade.model.pages[index] as Page;
				Cascade.model.pages.removeItemAt(index);
				affectedPage.setVO(Page(pages[i]).getVO());
				pages[i] = affectedPage;
			}
			
			if (prevPage)
				index = Cascade.model.pages.getItemIndex(prevPage);
			else if (newParent) {
				var children:ArrayCollection = newParent.parent ? newParent.parent.children : Cascade.model.siteTree;
				var parentIndex:Number = children.getItemIndex(newParent);
				if (parentIndex == children.length - 1) {
					if (newParent.parent)
						index = Cascade.model.pages.getItemIndex(newParent.parent);
					else
						index = Cascade.model.pages.length;
				} else
					index = Cascade.model.pages.getItemIndex(children[parentIndex + 1]);
			} else {
				index = Cascade.model.pages.length;
			}
			
			for (i = pages.length - 1; i >= 0; i--)
				Cascade.model.pages.addItemAt(pages[i], index);
			
			Cascade.busy.removeBusy(this);
//			Cascade.controller.execCommand("loadPages");
			dispatchExecutionComplete();
		}
		
		protected function fault(info:Object):void {
			trace(info);
			
			// remove page from new parent's childen array
			var children:ArrayCollection = newParent ? newParent.children : Cascade.model.siteTree;
			children.removeItemAt(children.getItemIndex(page));
			
			// put the page back into it's old parent's children array
			children = oldParent ? oldParent.children : Cascade.model.siteTree;
			var i:Number = Cascade.model.pages.getItemIndex(page);
			if (i == 0 || Cascade.model.pages[i - 1] == oldParent) {
				children.addItemAt(page, 0);
			} else {
				var prevSibling:Page;
				while (i--) {
					prevSibling = Cascade.model.pages[i] as Page;
					if (prevSibling.parent == oldParent)
						children.addItemAt(page, children.getItemIndex(prevSibling) + 1);
				}
			}
			
			Cascade.busy.removeBusy(this);
		}
	}
}